#include "driver_llcc68_interface.h"
#include "stm32f0xx_hal.h"
#include <stdarg.h>
#include <stdio.h>

extern SPI_HandleTypeDef hspi1;  // SPI1句柄（外部定义）

/* RESET 引脚 */
#define LLCC68_RESET_PORT     GPIOA
#define LLCC68_RESET_PIN      GPIO_PIN_0

/* BUSY 引脚 */
#define LLCC68_BUSY_PORT      GPIOA
#define LLCC68_BUSY_PIN       GPIO_PIN_1

/**
 * @brief  interface spi bus init
 */
uint8_t llcc68_interface_spi_init(void)
{
    // SPI 已由用户初始化
    return 0;
}

/**
 * @brief  interface spi bus deinit
 */
uint8_t llcc68_interface_spi_deinit(void)
{
    HAL_SPI_DeInit(&hspi1);
    return 0;
}

/**
 * @brief interface spi write/read
 */
uint8_t llcc68_interface_spi_write_read(uint8_t *in_buf, uint32_t in_len,
                                        uint8_t *out_buf, uint32_t out_len)
{
    if (HAL_SPI_Transmit(&hspi1, in_buf, in_len, HAL_MAX_DELAY) != HAL_OK)
        return 1;
    if (HAL_SPI_Receive(&hspi1, out_buf, out_len, HAL_MAX_DELAY) != HAL_OK)
        return 1;
    return 0;
}

/**
 * @brief  reset gpio init
 */
uint8_t llcc68_interface_reset_gpio_init(void)
{
    // GPIO已初始化
    return 0;
}

/**
 * @brief  reset gpio deinit
 */
uint8_t llcc68_interface_reset_gpio_deinit(void)
{
    return 0;
}

/**
 * @brief  reset gpio write
 */
uint8_t llcc68_interface_reset_gpio_write(uint8_t data)
{
    HAL_GPIO_WritePin(LLCC68_RESET_PORT, LLCC68_RESET_PIN, data ? GPIO_PIN_SET : GPIO_PIN_RESET);
    return 0;
}

/**
 * @brief  busy gpio init
 */
uint8_t llcc68_interface_busy_gpio_init(void)
{
    return 0;
}

/**
 * @brief  busy gpio deinit
 */
uint8_t llcc68_interface_busy_gpio_deinit(void)
{
    return 0;
}

/**
 * @brief  busy gpio read
 */
uint8_t llcc68_interface_busy_gpio_read(uint8_t *value)
{
    *value = HAL_GPIO_ReadPin(LLCC68_BUSY_PORT, LLCC68_BUSY_PIN) ? 1 : 0;
    return 0;
}

/**
 * @brief  delay in ms
 */
void llcc68_interface_delay_ms(uint32_t ms)
{
    volatile uint32_t i, j;
    for (i = 0; i < ms; i++)
    {
        for (j = 0; j < 8000; j++)  // 调整这个常数以匹配F030主频
        {
            __asm__ volatile ("nop");
        }
    }
}

/**
 * @brief  debug print
 */
void llcc68_interface_debug_print(const char *const fmt, ...)
{
    char buffer[128];
    va_list args;
    va_start(args, fmt);
    vsnprintf(buffer, sizeof(buffer), fmt, args);
    va_end(args);
    printf("%s", buffer);  // 请确保 printf 能正确输出
}

/**
 * @brief  接收中断回调处理
 */
void llcc68_interface_receive_callback(uint16_t type, uint8_t *buf, uint16_t len)
{
    switch (type)
    {
        case LLCC68_IRQ_TX_DONE :
            llcc68_interface_debug_print("llcc68: irq tx done.\n");
            break;
        case LLCC68_IRQ_RX_DONE :
            llcc68_interface_debug_print("llcc68: irq rx done.\n");
            break;
        case LLCC68_IRQ_PREAMBLE_DETECTED :
            llcc68_interface_debug_print("llcc68: irq preamble detected.\n");
            break;
        case LLCC68_IRQ_SYNC_WORD_VALID :
            llcc68_interface_debug_print("llcc68: irq valid sync word detected.\n");
            break;
        case LLCC68_IRQ_HEADER_VALID :
            llcc68_interface_debug_print("llcc68: irq valid header.\n");
            break;
        case LLCC68_IRQ_HEADER_ERR :
            llcc68_interface_debug_print("llcc68: irq header error.\n");
            break;
        case LLCC68_IRQ_CRC_ERR :
            llcc68_interface_debug_print("llcc68: irq crc error.\n");
            break;
        case LLCC68_IRQ_CAD_DONE :
            llcc68_interface_debug_print("llcc68: irq cad done.\n");
            break;
        case LLCC68_IRQ_CAD_DETECTED :
            llcc68_interface_debug_print("llcc68: irq cad detected.\n");
            break;
        case LLCC68_IRQ_TIMEOUT :
            llcc68_interface_debug_print("llcc68: irq timeout.\n");
            break;
        default :
            llcc68_interface_debug_print("llcc68: unknown code.\n");
            break;
    }
}
